package org.wms.minbearwcs.serivce.mission;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.wms.minbearwcs.dao.mission.inf.WcsMissionDao;
import org.wms.minbearwcs.entity.PO.wcs.mission.WcsMission;
import org.wms.minbearwcs.entity.PO.wcs.mission.type.MissionType;
import org.wms.minbearwcs.serivce.mission.processor.MissionProcessor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class MissionExecutor implements ApplicationContextAware {

    private final WcsMissionDao wcsMissionDao;


    private final HashMap<MissionType, List<MissionProcessor>> processorMap = new HashMap<>();

    public MissionExecutor(WcsMissionDao wcsMissionDao) {
        this.wcsMissionDao = wcsMissionDao;
        Thread missionExecutor = new Thread(exec(), "MissionExecutor");
        missionExecutor.setDaemon(true);
        missionExecutor.start();
    }

    // TODO : 可以按照需求不同类型任务使用不同的线程
    private Runnable exec(){
        return ()->{
            log.info("任务执行器开始执行");
            while (true){
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                    // 拿到所有未完成任务
                    List<WcsMission> wcsMissionList = wcsMissionDao.selectAll();
                    for (WcsMission wcsMission : wcsMissionList) {
                        processorMap.get(wcsMission.getEnumMissionType())
                                .forEach(a->a.process(wcsMission));
                    }
                } catch (Exception e) {
                    log.error("任务处理器出错",e);
                    break;
                }

            }

        };
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        String[] beanNamesForType = applicationContext.getBeanNamesForType(MissionProcessor.class);
        for (String beanName : beanNamesForType) {
            MissionProcessor processor = (MissionProcessor)applicationContext.getBean(beanName);
            MissionType missionType = processor.getMissionType();
            List<MissionProcessor> processorList = this.processorMap.computeIfAbsent(missionType, k -> new ArrayList<>());
            processorList.add(processor);
        }
    }
}
